package com.sl.biz.modular.debug.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.*;
import cn.hutool.system.SystemUtil;
import com.sl.biz.modular.debug.service.DebuggerBizService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.noear.socketd.SocketD;
import org.noear.socketd.transport.client.ClientSession;
import org.noear.socketd.transport.core.entity.EntityDefault;
import org.springframework.stereotype.Service;

import java.io.File;
import java.net.URL;

@Slf4j
@Service
@RequiredArgsConstructor
public class DebuggerBizServiceImpl implements DebuggerBizService {

    private String port = "15001";

    @Override
    public String connect() {
        String port = findDebugProcessService();
        return port;
    }

    @SneakyThrows
    @Override
    public Boolean disconnect() {

        ClientSession session = SocketD.createClient("sd:ws://127.0.0.1:" + port + "/?u=a&p=2")
                .open();
        boolean closing = session.isValid();
        if (BooleanUtil.isFalse(closing)) {
            return Boolean.FALSE;
        }
        session.sendAndRequest("close", new EntityDefault());
        return Boolean.TRUE;
    }

    private String findDebugProcessService() {

        //找文件是否存在
        boolean exist = FileUtil.exist("./debug-process-service.jar");
        if (BooleanUtil.isFalse(exist)) {
            createDebugProcessService();
        }

        //现在看看这个jar包是否已经启动了，如果没有启动，则需要启动一把
        String s = validDebugProcessRun();
        //记录一下pid disconnect的时候需要用到
        return s;
    }

    @SneakyThrows
    private String validDebugProcessRun() {

        //通过socket.d连接
        //如果不能连接正常返回（由心跳尝试不断连接）
        ClientSession session = SocketD.createClient("sd:ws://127.0.0.1:" + port + "/?u=a&p=2")
                .open();

        boolean closing = session.isValid();

        //验证失败，需要启动这个
        if (BooleanUtil.isFalse(closing)) {
            session.close();
            startDebugJar();
        } else {
            session.close();
        }
        return port;

    }

    public static void main(String[] args) {
        DebuggerBizServiceImpl debuggerBizService = new DebuggerBizServiceImpl();
        debuggerBizService.validDebugProcessRun();
    }


    @SneakyThrows
    private void startDebugJar() {
        File file = FileUtil.file("./");
        String cmd = "nohup java -Dport=" + port + " -jar debug-process-service.jar >> ./debug.log &";
        if (SystemUtil.getOsInfo().isWindows()) {
            cmd = "javaw -Dport=" + port + " -jar debug-process-service.jar";
        }
        RuntimeUtil.exec(new String[]{}, file, cmd);
    }


    @SneakyThrows
    private void createDebugProcessService() {
        URL resourceURL  = ClassUtil.getResourceURL("debug-process-service.jar");

        if(ObjectUtil.isNull(resourceURL)){
            return;
        }
        byte[] buffer = IoUtil.readBytes(URLUtil.getStream(resourceURL));
        if (ArrayUtil.isEmpty(buffer)) {
            log.error("在运行环境中没有找到这个jar包");
            return;
        }

        //把这个包copy出去
        File file = FileUtil.file("./debug-process-service.jar");
        file.createNewFile();
        IoUtil.write(FileUtil.getOutputStream(file), true, buffer);
    }
}
